﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Projecturo.ProjecturoClient.Connection;
using Projecturo.Model;
using Projecturo.ProjecturoClient.Command;
using System.Windows.Input;

namespace Projecturo.ProjecturoClient.ViewModel.UserManagement
{
    public class UserManagementViewModel : WorkspaceViewModel
    {
        private const string UserManagementDisplayName = "User Management";
        private ObservableCollection<ViewModelBase> users;
        private ObservableCollection<Projecturo.Model.Project> allProjects;
        private Projecturo.Model.Project selectedProject;
        private Projecturo.Model.Project selectedUserProject;
        private ViewModelBase selectedUser;
        private DelegateCommand newUserCommand;
        private DelegateCommand saveUserCommand;
        private DelegateCommand deleteUserCommand;
        private DelegateCommand<ObservableCollection<Projecturo.Model.Project>> addProjectCommand;
        private DelegateCommand<ObservableCollection<Projecturo.Model.Project>> removeProjectCommand;
        private bool userCreationMode = false;

        public override string DisplayName
        {
            get
            {
                return UserManagementDisplayName;
            }
            protected set
            {
                base.DisplayName = value;
            }
        }

        public ICommand NewUserCommand
        {
            get
            {
                if (this.newUserCommand == null)
                {
                    this.newUserCommand = new DelegateCommand(CreateNewUser);
                }
                return this.newUserCommand;
            }
        }

        private void CreateNewUser()
        {
            SelectedUser = ViewModelManager.Instance.CreateViewModel(typeof(User), this);
            this.userCreationMode = true;
        }

        public ICommand DeleteUserCommand
        {
            get
            {
                if (this.deleteUserCommand == null)
                {
                    this.deleteUserCommand = new DelegateCommand(DeleteUser, CanDeleteUser);
                }
                return this.deleteUserCommand;
            }
        }

        private void DeleteUser()
        {
            SelectedUser.DeleteCommand.Execute(null);
            SelectedUser = null;
            this.OnPropertyChanged("Users");
        }

        private bool CanDeleteUser()
        {
            return SelectedUser != null && !userCreationMode;
        }

        public ICommand SaveUserCommand
        {
            get
            {
                if (this.saveUserCommand == null)
                {
                    this.saveUserCommand = new DelegateCommand(SaveUser, CanSaveUser);
                }
                return this.saveUserCommand;
            }
        }

        private void SaveUser()
        {
            SelectedUser.SaveCommand.Execute(null);
            this.userCreationMode = false;
            this.Update();
        }

        private bool CanSaveUser()
        {
            return SelectedUser != null;
        }

        public Projecturo.Model.Project SelectedProject
        {
            get { return this.selectedProject; }
            set
            {
                if (this.selectedProject == value)
                    return;
                this.selectedProject = value;
                OnPropertyChanged("SelectedProject");
            }
        }

        public Projecturo.Model.Project SelectedUserProject
        {
            get { return this.selectedUserProject; }
            set
            {
                if (this.selectedUserProject == value)
                    return;
                this.selectedUserProject = value;
                OnPropertyChanged("SelectedUserProject");
            }
        }

        public ICommand AddProjectCommand
        {
            get
            {
                if (this.addProjectCommand == null)
                {
                    this.addProjectCommand = new DelegateCommand<ObservableCollection<Projecturo.Model.Project>>(AddProject);
                }
                return this.addProjectCommand;
            }
        }

        public void AddProject(ObservableCollection<Projecturo.Model.Project> projects)
        {
            if (this.SelectedProject != null && !projects.Contains(this.SelectedProject))
                projects.Add(SelectedProject);
        }

        public ICommand RemoveProjectCommand
        {
            get
            {
                if (this.removeProjectCommand == null)
                {
                    this.removeProjectCommand = new DelegateCommand<ObservableCollection<Projecturo.Model.Project>>(RemoveProject);
                }
                return this.removeProjectCommand;
            }
        }

        public void RemoveProject(ObservableCollection<Projecturo.Model.Project> projects)
        {
            if (this.SelectedUserProject != null)
                projects.Remove(this.SelectedUserProject);
        }

        public ViewModelBase SelectedUser
        {
            get { return selectedUser; }
            set
            {
                if (selectedUser == value)
                    return;
                selectedUser = value;
                OnPropertyChanged("SelectedUser");
                OnPropertyChanged("IsReadOnly");
            }
        }

        public bool IsReadOnly
        {
            get 
            { 
                return SelectedUser != null; 
            }
        }

        public ObservableCollection<ViewModelBase> Users
        {
            get { return this.users; }
        }

        public ObservableCollection<Projecturo.Model.Project> AllProjects
        {
            get { return this.allProjects; }
        }

        protected override void OnViewModelCreated()
        {
            base.OnViewModelCreated();
            LoadUsers();
            LoadAllProjects();
        }

        private void LoadUsers()
        {
            if (this.users == null)
            { 
                this.users = new ObservableCollection<ViewModelBase>(); 
            }
            else
            {
                this.users.Clear();
            }
            IList<User> userList = Connector.Connectivity.Storage.GetList<User>();
            foreach (User user in userList)
            {
                ViewModelBase viewModel = ViewModelManager.Instance.CreateViewModel(typeof(User), this);
                viewModel.SetModel(user);
                this.users.Add(viewModel);
            }
        }

        private void LoadAllProjects()
        {
            if (this.allProjects == null)
            {
                this.allProjects = new ObservableCollection<Projecturo.Model.Project>();
            }
            else
            {
                this.allProjects.Clear();
            }
            IList<Projecturo.Model.Project> projects = Connector.Connectivity.Storage.GetList<Projecturo.Model.Project>();
            foreach (Projecturo.Model.Project project in projects)
            {
                this.allProjects.Add(project);
            }
        }

        public override void Update()
        {
            base.Update();
            LoadUsers();
            LoadAllProjects();
        }
    }
}
